import FlowInstance from '@/store/entities/flow/flow-instance/flow-instance';
import FlowNode from '@/store/entities/flow/flow-data/node';
import FlowLine from '@/store/entities/flow/flow-data/line';
import Condition from '@/store/entities/flow/flow-data/condition';
interface Node{
    id:string,
    flowNode:FlowNode,
}
interface FromLine{
    from:string,
    flowLines:FlowLine[],
}
interface ToLine{
    to:string,
    flowLines:FlowLine[],
}
export default class Runtime{
    public nodes:Node[]=[];
    public lines:FlowLine[]=[];
    public fromLines:FromLine[]=[];
    public toLines:ToLine[]=[];
    public currentNode:FlowNode;
    public nextNode:FlowNode;
    public startNode:FlowNode;
    public EndNode:FlowNode;
    public formData:string='';
    private schemeContent:any;

    constructor(instance:FlowInstance) {
        this.schemeContent=JSON.parse(instance.flowSchemeContent);
        this.initNodes(this.schemeContent);
        this.initLines(this.schemeContent);

        let currentNodeId='';
        if(instance.state===4){
            currentNodeId=instance.prevNodeId;
        }else{
            currentNodeId=!instance.activityNodeId?this.startNode.id:instance.activityNodeId;
        }

        this.currentNode=this.nodes.find(i=>i.id===currentNodeId).flowNode;
        if(this.currentNode.type==='end'){
            this.nextNode=null;
        }else{
            const nextNodeId=this.getNextNodeId();
            this.nextNode=this.nodes.find(i=>i.id===nextNodeId).flowNode;
        }
    }

    private getNextNodeId(nodeId?:string):string{
        const lines:FlowLine[]=!nodeId?this.fromLines.find(i=>i.from===this.currentNode.id).flowLines:this.fromLines.find(i=>i.from===nodeId).flowLines;
        if(lines.length===0){
            throw new Error('无法找到下一个节点')
        }
        if(!this.formData){
            return lines[0].to;
        }
        const formData:any=JSON.parse(this.formData.toLowerCase());
        lines.forEach(line=>{
            if(line.conditions.length!==0 && line.compare(formData)){
                return line.to;
            }
        });
        return lines[0].to;
    }
    private initNodes(schemeContent:any):void{
        schemeContent.nodeList.forEach(node=>{
            if(!this.nodes.find(i=>i.id===node.id)){
                this.nodes.push({id:node.id,flowNode:node});
            }
            if(node.type==='start'){
                this.startNode=node;
            }
            if(node.type==='end'){
                this.EndNode=node;
            }
        });
    }
    private initLines(schemeContent:any):void{
        schemeContent.lineList.forEach(line=>{
            const conditions:Condition[]=[];
            line.conditions.forEach(condition=>{
                conditions.push(condition);
            });
            conditions.forEach((condition,index)=>{
                if(!condition.field || !condition.operation || !condition.value){
                    line.conditions.splice(index,1);
                }
            });
            this.lines.push(line);
            if(!this.fromLines.find(i=>i.from===line.from)){
                const ls:FlowLine[]=[line];
                this.fromLines.push({from:line.from,flowLines:ls});
            }else{
                this.fromLines.find(i=>i.from===line.from).flowLines.push(line);
            }
            if(!this.toLines.find(i=>i.to===line.to)){
                const ls:FlowLine[]=[line];
                this.toLines.push({to:line.to,flowLines:ls});
            }else{
                this.toLines.find(i=>i.to===line.to).flowLines.push(line);
            }
        });
    }
}
